﻿using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using DAL.Clipboard;
using DAL.File;

namespace BLL.Utils
{
    public static class SerHelper
    {
        public static void SaveContent(ClipboardContent content, IFileAccess fs, string path, string pass = null)
        {
            var doEncrypt = pass != null;
            var endStr = doEncrypt ? ".enc" : "";

            Action<string, byte[]> save = (fileName, outputBytes) =>
            {
                if (doEncrypt)
                    outputBytes = PassEncHelper.EncryptData(pass, outputBytes);

                fs.WriteFile(path + fileName + endStr, outputBytes);
            };

            Action<string, string> saveText = (fileName, text) =>
            {
                var outputBytes = Encoding.UTF8.GetBytes(text);

                save(fileName, outputBytes);
            };

            if (content.Image != null)
            {
                var memStream = new MemoryStream();
                content.Image.ToPng().Save(memStream);
                var outputBytes = memStream.ToArray();

                save("image.png", outputBytes);
            }

            if (content.Text != null)
                saveText("text.txt", content.Text);

            if (content.Rtf != null)
                saveText("text.rtf", content.Rtf);

            if (content.Html != null)
                saveText("text.html", content.Html);

            saveText("date.txt", content.Time.ToString(CultureInfo.InvariantCulture));
        }

        public static ClipboardContent LoadContent(IFileAccess fs, string path, string pass = null)
        {
            var doEncrypt = pass != null;
            var endStr = doEncrypt ? ".enc" : "";

            Func<string, byte[]> load = fileName =>
            {
                var outputBytes = fs.ReadFile(path + fileName + endStr);
                if (outputBytes == null)
                    return null;

                if (doEncrypt)
                    outputBytes = PassEncHelper.DecryptData(pass, outputBytes);

                return outputBytes;
            };

            Func<string, string> loadText = fileName =>
            {
                var outputBytes = load(fileName);

                if (outputBytes == null)
                    return null;

                return Encoding.UTF8.GetString(outputBytes);
            };

            Func<string, BitmapSource> loadImage = fileName =>
            {
                var outputBytes = load(fileName);

                if (outputBytes == null)
                    return null;

                var memStream = new MemoryStream(outputBytes);
                return new PngBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default).Frames[0];
            };

            var dateStr = loadText("date.txt");
            DateTime time;
            if (dateStr == null)
                time = DateTime.Now;
            else
            {
                var success = DateTime.TryParse(dateStr, out time);
                if (!success)
                    time = DateTime.Now;
            }

            var text = loadText("text.txt");
            var rtf = loadText("text.rtf");
            var html = loadText("text.html");
            var image = loadImage("image.png");

            if (text == null && rtf == null &&
                html == null && image == null)
                return null;
            else
                return new ClipboardContent
                {
                    Path = path,
                    Time = time,
                    Text = text,
                    Rtf = rtf,
                    Html = html,
                    Image = image,
                };
        }
    }
}